#!/usr/bin/env python3
"""
S3 Bucket List Tool - ListBuckets API 演示工具

这个工具演示如何使用 ListBuckets API 列出账户下的所有存储桶。

使用示例:
    python s3_bucket_list.py
    python s3_bucket_list.py --host http://localhost:8000
    python s3_bucket_list.py --format json
    python s3_bucket_list.py --verbose
"""

import argparse
import boto3
import json
import sys
from datetime import datetime, timezone
from botocore.config import Config
from botocore.exceptions import ClientError, NoCredentialsError


class BucketListClient:
    """S3 桶列表客户端"""
    
    def __init__(self, endpoint_url='http://localhost:8000', 
                 access_key='AKIAIOSFODNN7EXAMPLE', 
                 secret_key='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
                 region='us-east-1'):
        """
        初始化桶列表客户端
        
        Args:
            endpoint_url: S3 服务端点
            access_key: AWS Access Key
            secret_key: AWS Secret Key
            region: AWS 区域
        """
        self.endpoint_url = endpoint_url
        self.access_key = access_key
        self.secret_key = secret_key
        self.region = region
        self._client = None
    
    def _get_client(self):
        """获取 S3 客户端"""
        if self._client is None:
            self._client = boto3.client(
                's3',
                endpoint_url=self.endpoint_url,
                aws_access_key_id=self.access_key,
                aws_secret_access_key=self.secret_key,
                region_name=self.region,
                config=Config(s3={'addressing_style': 'path'})
            )
        return self._client
    
    def list_buckets(self):
        """简单格式显示桶列表"""
        try:
            s3_client = self._get_client()
            response = s3_client.list_buckets()
            buckets = response['Buckets']
            
            print("📚 账户下的所有桶:")
            print("-" * 50)
            
            if not buckets:
                print("📭 暂无桶")
                return True
                
            # 按创建时间排序（最新的在前）
            buckets.sort(key=lambda x: x['CreationDate'], reverse=True)
            
            for bucket in buckets:
                name = bucket['Name']
                created = bucket['CreationDate'].strftime('%Y-%m-%d %H:%M:%S')
                age = self._format_bucket_age(bucket['CreationDate'])
                print(f"🗂️  {name:<30} 创建时间: {created} ({age})")
                
            print(f"\n📊 总计: {len(buckets)} 个桶")
            return True
            
        except ClientError as e:
            error_code = e.response['Error']['Code']
            error_msg = e.response['Error']['Message']
            print(f"❌ S3 错误 [{error_code}]: {error_msg}")
            return False
        except NoCredentialsError:
            print("❌ 错误: 未找到 AWS 凭据")
            return False
        except Exception as e:
            print(f"❌ 未知错误: {e}")
            return False
    
    def list_buckets_verbose(self):
        """详细格式显示桶列表"""
        try:
            s3_client = self._get_client()
            response = s3_client.list_buckets()
            buckets = response['Buckets']
            
            print("📚 详细桶信息:")
            print("=" * 70)
            
            if not buckets:
                print("📭 暂无桶")
                return True
                
            # 按创建时间分组
            now = datetime.now(timezone.utc)
            groups = {
                "今天": [],
                "本周": [],
                "本月": [],
                "更早": []
            }
            
            for bucket in buckets:
                age_days = (now - bucket['CreationDate']).days
                if age_days == 0:
                    groups["今天"].append(bucket)
                elif age_days < 7:
                    groups["本周"].append(bucket)
                elif age_days < 30:
                    groups["本月"].append(bucket)
                else:
                    groups["更早"].append(bucket)
            
            # 显示分组信息
            for group_name, group_buckets in groups.items():
                if group_buckets:
                    print(f"\n🗓️  {group_name} ({len(group_buckets)} 个):")
                    print("-" * 50)
                    
                    for bucket in group_buckets:
                        name = bucket['Name']
                        created = bucket['CreationDate'].strftime('%Y-%m-%d %H:%M:%S')
                        age = self._format_bucket_age(bucket['CreationDate'])
                        
                        print(f"   🗂️  桶名称: {name}")
                        print(f"       📅 创建时间: {created}")
                        print(f"       ⏰ 年龄: {age}")
                        print(f"       🌐 区域: us-east-1 (默认)")
                        print()
            
            print(f"📊 总体统计:")
            print(f"   • 总桶数: {len(buckets)}")
            print(f"   • 最新桶: {min(buckets, key=lambda x: x['CreationDate'])['Name'] if buckets else 'N/A'}")
            print(f"   • 最旧桶: {max(buckets, key=lambda x: x['CreationDate'])['Name'] if buckets else 'N/A'}")
            
            return True
            
        except Exception as e:
            print(f"❌ 错误: {e}")
            return False
    
    def list_buckets_json(self):
        """JSON 格式输出桶列表"""
        try:
            s3_client = self._get_client()
            response = s3_client.list_buckets()
            buckets = response['Buckets']
            
            # 转换为 JSON 友好的格式
            result = {
                "buckets": [],
                "total_count": len(buckets),
                "query_time": datetime.now().isoformat()
            }
            
            for bucket in buckets:
                bucket_info = {
                    "name": bucket['Name'],
                    "creation_date": bucket['CreationDate'].isoformat(),
                    "age_days": (datetime.now(timezone.utc) - bucket['CreationDate']).days
                }
                result["buckets"].append(bucket_info)
            
            print(json.dumps(result, indent=2, ensure_ascii=False))
            return True
            
        except ClientError as e:
            error_code = e.response['Error']['Code']
            error_msg = e.response['Error']['Message']
            error_result = {
                "error": True,
                "error_code": error_code,
                "error_message": error_msg
            }
            print(json.dumps(error_result, indent=2, ensure_ascii=False))
            return False
        except NoCredentialsError:
            error_result = {
                "error": True,
                "error_code": "NoCredentials",
                "error_message": "未找到 AWS 凭据"
            }
            print(json.dumps(error_result, indent=2, ensure_ascii=False))
            return False
        except Exception as e:
            error_result = {
                "error": True,
                "error_code": "Unknown",
                "error_message": str(e)
            }
            print(json.dumps(error_result, indent=2, ensure_ascii=False))
            return False
    
    def _format_bucket_age(self, created_date):
        """计算并格式化桶的年龄"""
        now = datetime.now(timezone.utc)
        age = now - created_date
        
        if age.days == 0:
            return "今天"
        elif age.days == 1:
            return "昨天"
        elif age.days < 7:
            return f"{age.days} 天前"
        elif age.days < 30:
            weeks = age.days // 7
            return f"{weeks} 周前"
        elif age.days < 365:
            months = age.days // 30
            return f"{months} 个月前"
        else:
            years = age.days // 365
            return f"{years} 年前"


def parse_args():
    """解析命令行参数"""
    parser = argparse.ArgumentParser(
        description='S3 ListBuckets API 演示工具',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
示例:
  %(prog)s                           # 简单格式列出所有桶
  %(prog)s --host http://localhost:8000  # 指定服务器地址
  %(prog)s --format json             # JSON 格式输出
  %(prog)s --verbose                 # 详细格式输出
  %(prog)s --access-key KEY --secret-key SECRET  # 指定凭据
        """
    )
    
    parser.add_argument(
        '--host',
        default='http://localhost:8000',
        help='S3 服务端点 (默认: http://localhost:8000)'
    )
    
    parser.add_argument(
        '--access-key',
        default='AKIAIOSFODNN7EXAMPLE',
        help='AWS Access Key (默认: 测试密钥)'
    )
    
    parser.add_argument(
        '--secret-key',
        default='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
        help='AWS Secret Key (默认: 测试密钥)'
    )
    
    parser.add_argument(
        '--region',
        default='us-east-1',
        help='AWS 区域 (默认: us-east-1)'
    )
    
    parser.add_argument(
        '--format',
        choices=['simple', 'verbose', 'json'],
        default='simple',
        help='输出格式 (默认: simple)'
    )
    
    parser.add_argument(
        '--verbose',
        action='store_true',
        help='详细输出模式 (等同于 --format verbose)'
    )
    
    return parser.parse_args()


def main():
    """主函数"""
    args = parse_args()
    
    # 如果指定了 --verbose，覆盖 format 设置
    if args.verbose:
        args.format = 'verbose'
    
    # 创建客户端
    client = BucketListClient(
        endpoint_url=args.host,
        access_key=args.access_key,
        secret_key=args.secret_key,
        region=args.region
    )
    
    # 根据格式执行相应操作
    success = False
    if args.format == 'simple':
        success = client.list_buckets_simple()
    elif args.format == 'verbose':
        success = client.list_buckets_verbose()
    elif args.format == 'json':
        success = client.list_buckets_json()
    
    # 设置退出码
    sys.exit(0 if success else 1)


if __name__ == '__main__':
    main()
